package com.xwj.controller.front;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.github.pagehelper.PageInfo;
import com.google.gson.JsonObject;
import com.xwj.Enums.StatusInfoEnum;
import com.xwj.config.FileUploadCosConfig;
import com.xwj.data.StaticData;
import com.xwj.dto.CreateCloudHouseInfoDto;
import com.xwj.dto.HouseInfoDto;
import com.xwj.dto.OrderInfoDto;
import com.xwj.entity.*;
import com.xwj.service.Impl.RaCloudHourseServiceImpl;
import com.xwj.service.Impl.RaHouseInfoServiceImpl;
import com.xwj.service.Impl.RaOrderServiceImpl;
import com.xwj.service.Impl.RaStatusInfoServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;
import java.util.concurrent.ExecutionException;

@RestController
@RequestMapping("/front/myCenter/houseInfo/")
@Slf4j
public class FrontHouseInfoController {

    @Autowired
    private RaHouseInfoServiceImpl raHouseInfoService;
    @Autowired
    private RaOrderServiceImpl raOrderService;
    @Autowired
    private RaCloudHourseServiceImpl raCloudHourseService;
    @Autowired
    private RaStatusInfoServiceImpl raStatusInfoService;
    @Autowired
    private FileUploadCosConfig fileUploadCos;

    /**
     * 我发布的房子
     *
     * @param modelAndView
     * @return
     */
    @RequestMapping(value = "houseInfoList", method = RequestMethod.GET)
    public ModelAndView houseInfoList(ModelAndView modelAndView) {
        String label = StatusInfoEnum.HouseInfo.getName();
        modelAndView.addObject("cloudStatus", raStatusInfoService.findStatusByLabel(label));
        modelAndView.setViewName("/front/myHouse/houseInfoList");
        return modelAndView;
    }

    /**
     * 发布新房
     *
     * @param modelAndView
     * @return
     */
    @RequestMapping(value = "addHouse", method = RequestMethod.GET)
    public ModelAndView addHouse(ModelAndView modelAndView) {
        modelAndView.setViewName("/front/myHouse/addHouse");
        return modelAndView;
    }

    /**
     * 前台点击进入房屋列表页面
     *
     * @param modelAndView
     * @param cloudId
     * @return
     */
    @RequestMapping(value = "frontHouseList", method = RequestMethod.GET)
    public ModelAndView frontHouseList(ModelAndView modelAndView, int cloudId) {
        List<RaHourseInfo> raHourseInfos = raHouseInfoService.frontFindHouseInfoByCloudIdWithNoPage(cloudId);
        modelAndView.addObject("houseInfos", raHourseInfos);
        modelAndView.setViewName("/front/houseListView");
        return modelAndView;
    }

    /**
     * 房屋详情
     *
     * @param modelAndView
     * @param houseId
     * @return
     */
    @RequestMapping(value = "frontHouseInfo", method = RequestMethod.GET)
    public ModelAndView frontHouseInfo(ModelAndView modelAndView, String houseId) {
        RaHourseInfo raHourseInfo = raHouseInfoService.findHouseInfoByIdSync(houseId);
        modelAndView.addObject("raHourseInfo", raHourseInfo);
        modelAndView.setViewName("/front/houseInfoView");
        return modelAndView;
    }

    /**
     * 显示或查找信息列表(前台点击云图展示相关列表)
     *
     * @param pageIndex
     * @param pageSize
     * @param cloudId
     * @return
     */
    @RequestMapping(value = "houseInfoDetailList", method = {RequestMethod.POST, RequestMethod.GET})
    public Map<String, Object> houseInfoDetailList(@RequestParam(value = "page") Integer pageIndex,
                                                   @RequestParam(value = "limit") Integer pageSize,
                                                   @RequestParam(value = "cloudId", required = false) Integer cloudId,
                                                   @RequestParam(value = "key", required = false) String key) {
        PageInfo<RaHourseInfo> page;
        HouseInfoDto houseInfoDto = null;
        if (key != null) houseInfoDto = JSON.parseObject(key, new TypeReference<HouseInfoDto>() {
        });
        if (houseInfoDto == null)
            page = raHouseInfoService.frontFindHouseInfoByCloudId(pageIndex, pageSize, cloudId);
        else {
            houseInfoDto.setStatus("0");
            page = raHouseInfoService.findByProperty(pageIndex, pageSize, houseInfoDto);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("code", 0);
        map.put("msg", "");
        map.put("count", page.getTotal());
        map.put("data", page.getList());
        return map;
    }


    /**
     * 我发布的房子
     * 显示/查询
     *
     * @param pageIndex
     * @param pageSize
     * @param key
     * @param request
     * @return
     */
    @RequestMapping(value = "myHouseInfoDetail", method = RequestMethod.POST)
    public Map<String, Object> myHouseInfoDetail(@RequestParam(value = "page") Integer pageIndex,
                                                 @RequestParam(value = "limit") Integer pageSize,
                                                 @RequestParam(value = "key", required = false) String key,
                                                 HttpServletRequest request) {
        ServletContext context = request.getServletContext();
        String userId = (String) context.getAttribute(StaticData.REGISTER_USER_LOGIN_ATTRIBUTE);
        PageInfo<RaHourseInfo> page;
        HouseInfoDto houseInfoDto = null;
        if (key != null) houseInfoDto = JSON.parseObject(key, new TypeReference<HouseInfoDto>() {
        });
        if (houseInfoDto == null)
            page = raHouseInfoService.findHouseInfoByUserId(pageIndex, pageSize, userId);
        else {
            houseInfoDto.setUserId(userId);
            page = raHouseInfoService.frontFindByProperty(pageIndex, pageSize, houseInfoDto);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("code", 0);
        map.put("msg", "");
        map.put("count", page.getTotal());
        map.put("data", page.getList());
        return map;
    }

    /**
     * 我租的房子
     * 显示/查询
     *
     * @param pageIndex
     * @param pageSize
     * @param key
     * @param request
     * @return
     */
    @RequestMapping(value = "myRentHourseInfoDetail", method = RequestMethod.POST)
    public Map<String, Object> myRentHourseInfoDetail(@RequestParam(value = "page") Integer pageIndex,
                                                      @RequestParam(value = "limit") Integer pageSize,
                                                      @RequestParam(value = "key", required = false) String key,
                                                      HttpServletRequest request) {
        ServletContext context = request.getServletContext();
        String userId = (String) context.getAttribute(StaticData.REGISTER_USER_LOGIN_ATTRIBUTE);
        final PageInfo<RaHourseInfo> page = new PageInfo<>(Collections.emptyList());
        OrderInfoDto orderInfoDto = null;
        if (key != null) orderInfoDto = JSON.parseObject(key, new TypeReference<OrderInfoDto>() {
        });
        if (orderInfoDto == null) {
            PageInfo<RaOrder> orderPage = raOrderService.findOrderByTenantIdWithPage(pageIndex, pageSize, userId);
            orderPage.getList().forEach(raOrder -> {
                RaHourseInfo raHourseInfo = raHouseInfoService.findHouseInfoById(raOrder.getHourseId());
                page.getList().add(raHourseInfo);
            });
        } else {
            orderInfoDto.setTenantId(userId);
            PageInfo<RaOrder> orderPage = raOrderService.frontFindByPropertyWithPage(pageIndex, pageSize, orderInfoDto);
            orderPage.getList().forEach(raOrder -> {
                RaHourseInfo raHourseInfo = raHouseInfoService.findHouseInfoById(raOrder.getHourseId());
                page.getList().add(raHourseInfo);
            });
        }
        Map<String, Object> map = new HashMap<>();
        map.put("code", 0);
        map.put("msg", "");
        map.put("count", page.getTotal());
        map.put("data", page.getList());
        return map;
    }

    /**
     * 发布/更新 新房
     *
     * @param cloudData
     * @param phone
     * @param duiringTime
     * @param id
     * @param houseInfoDetailEntity
     * @param request
     * @return
     * @throws IOException
     * @throws URISyntaxException
     */
    @RequestMapping(value = "pushNewHouse", method = RequestMethod.POST)
    public Map<String, Object> pushNewHouse(@RequestParam(value = "cloudInfo", required = false) String cloudData,
                                            @RequestParam(value = "phone", required = false) String phone,
                                            @RequestParam(value = "duiringTime", required = false) Integer duiringTime,
                                            @RequestParam(value = "id", required = false) String id,
                                            HouseInfoDetailEntity houseInfoDetailEntity,
                                            HttpServletRequest request) throws IOException, URISyntaxException {
        Map<String, Object> map = new HashMap<>();
        ServletContext context = request.getServletContext();
        String userId = (String) context.getAttribute(StaticData.REGISTER_USER_LOGIN_ATTRIBUTE);
        if (StringUtils.isNotBlank(cloudData)) { //发布
            CreateCloudHouseInfoDto cloudHouseInfoDto = JSON.parseObject(cloudData, new TypeReference<CreateCloudHouseInfoDto>() {
            });
            Integer cloudId = raCloudHourseService.findCloudIdByLocation(cloudHouseInfoDto.getLon(), cloudHouseInfoDto.getLat());
            if (cloudId == null) {
                ResponseInfoEntity responseInfoEntity = raCloudHourseService.createOrUpdateOneReuest(cloudHouseInfoDto);
                if (responseInfoEntity.getInfo().equalsIgnoreCase("ok")) {
                    RaCloudHourse raCloudHourse = new RaCloudHourse(responseInfoEntity.getId(), cloudHouseInfoDto.getName(),
                            cloudHouseInfoDto.getAddress(), cloudHouseInfoDto.getLon(), cloudHouseInfoDto.getLat());
                    if (raCloudHourseService.insertOne(raCloudHourse) > 0)
                        cloudId = responseInfoEntity.getId();
                    else {
                        map.put("msg", "数据保存失败，请稍后重试");
                        return map;
                    }
                } else {
                    map.put("msg", "云图上传数据失败，导致添加失败，请稍后重试");
                    return map;
                }
            }
            Set<Object> urlSet = raHouseInfoService.getAccressUrlSet(userId + "_upload_house_picture");
            int index = 1;
            List<PhotoDetail> photoDetailList = new ArrayList<>();
            for (Object str : urlSet) {
                JSONObject jsonObject = JSON.parseObject((String) str);
                String url = jsonObject.getString("access_url");
                String name = jsonObject.getString("name");
                PhotoDetail photoDetail = new PhotoDetail(name, index, url, url);
                photoDetailList.add(photoDetail);
                index++;
            }
            HouseInfoPhotosEntity houseInfoPhotosEntity = new HouseInfoPhotosEntity();
            houseInfoPhotosEntity.setData(photoDetailList);
            houseInfoDetailEntity.setPhotos(houseInfoPhotosEntity);
            if (houseInfoDetailEntity.getPhotos().getData().size() == 0) {
                map.put("msg", "图片未上传或长时间未保存已丢失，请上传图片");
                return map;
            }
            RaHourseInfo raHourseInfo = new RaHourseInfo(userId, phone, cloudId, duiringTime, JSON.toJSONString(houseInfoDetailEntity));
            if (raHouseInfoService.insertOneHouse(raHourseInfo) > 0) {
                raHouseInfoService.deleteSet(userId + "_upload_house_picture");
                map.put("msg", "添加成功");
            } else
                map.put("msg", "添加失败");
        } else { //更新
            Map<String, Object> data = new HashMap<>();
            RaHourseInfo raHourseInfo = raHouseInfoService.findHouseInfoById(id);
            if (raHourseInfo.getStatus() != 0) {
                map.put("msg", "房子当前状态不是出租中，不可更改");
                return map;
            }
            if (raHourseInfo != null) {
                HouseInfoDetailEntity detailEntity =
                        JSON.parseObject(raHourseInfo.getDetailInfo(), new TypeReference<HouseInfoDetailEntity>() {
                        });
                if (houseInfoDetailEntity.getPhotos() == null) //若没上传图片则用原来的。否则覆盖原来的图片用最新的
                    houseInfoDetailEntity.setPhotos(detailEntity.getPhotos());
            }
            data.put("id", id);
            data.put("detailInfo", JSON.toJSONString(houseInfoDetailEntity));
            if (raHouseInfoService.updateDetail(data) > 0) {
                raHouseInfoService.deleteSet(userId + "_upload_house_picture");
                map.put("msg", "更新成功");
            } else
                map.put("msg", "更新失败");
        }
        return map;
    }

    @RequestMapping(value = "updateProperty", method = RequestMethod.POST)
    public Map<String, Object> updateProperty(HouseInfoDto houseInfoDto, HttpServletRequest request) throws ExecutionException, InterruptedException {
        Map<String, Object> map = new HashMap<>();
        if (Integer.parseInt(houseInfoDto.getStatus()) > 0) {
            map.put("msg", "不可修改为该状态");
            return map;
        }
        ServletContext context = request.getServletContext();
        String userId = (String) context.getAttribute(StaticData.REGISTER_USER_LOGIN_ATTRIBUTE);
        houseInfoDto.setUserId(userId);
        if (raHouseInfoService.updatePropertySync(houseInfoDto).get())
            map.put("msg", "更新成功");
        else
            map.put("msg", "数据操作异常");
        return map;
    }


    @RequestMapping(value = "batch/upload", method = RequestMethod.POST)
    public Map<String, Object> handleFileUpload(HttpServletRequest request) {
        ServletContext context = request.getServletContext();
        String accountid = (String) context.getAttribute(StaticData.REGISTER_USER_LOGIN_ATTRIBUTE);
        Map<String, Object> map = new HashMap<>();
        String localPathDir = "/apartmentphoto";
        String localRealPathDir = request.getSession().getServletContext().getRealPath(localPathDir);
        File localSaveFile = new File(localRealPathDir);
        if (!localSaveFile.exists()) localSaveFile.mkdirs();
        String result = null;
        try {
            MultipartFile multipartFile = ((MultipartHttpServletRequest) request).getFile("file");
            String fileName = localRealPathDir + File.separator + multipartFile.getOriginalFilename();
            File file = new File(fileName);
            multipartFile.transferTo(file);
            result = fileUploadCos.uploadFile("/apartmentphoto/", fileName, multipartFile.getOriginalFilename());
            JSONObject jsonObject = JSON.parseObject(result);
            if (jsonObject.getInteger("code") == 0) {
                JsonObject jsonObject1 = new JsonObject();
                jsonObject1.addProperty("access_url", jsonObject.getJSONObject("data").getString("access_url"));
                jsonObject1.addProperty("name", multipartFile.getOriginalFilename());
                raHouseInfoService.accressUrlSet(jsonObject1.toString(), accountid + "_upload_house_picture");
            }
        } catch (IOException e) {
            log.error("注册用户{}多照片上传失败异常:", accountid, e);
            e.printStackTrace();
        }
        map.put("result", result);
        return map;
    }

    /**
     * 删除我发布的房子或我租的房子
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "deleteById", method = RequestMethod.POST)
    public Map<String, Object> deleteById(@RequestParam("id") String id) throws ExecutionException, InterruptedException {
        List<String> ids = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        ids.add(id);
        if (raHouseInfoService.updateDelflag(ids).get())
            map.put("msg", "删除成功");
        else
            map.put("msg", "数据操作异常");
        return map;
    }

    /**
     * 批量删除
     *
     * @param mydata
     * @return
     */
    @RequestMapping(value = "deleteBatchById", method = RequestMethod.POST)
    public Map<String, Object> deleteBatchById(@RequestParam(value = "mydata", required = false) String mydata) throws ExecutionException, InterruptedException {
        Map<String, Object> map = new HashMap<>();
        List<RaHourseInfo> raHourseInfoList = JSON.parseArray(mydata, RaHourseInfo.class);
        if (raHourseInfoList.size() == 0) {
            map.put("msg", "未选中任何选项");
            return map;
        }
        List<String> ids = raHouseInfoService.parseListId(raHourseInfoList);
        if (raHouseInfoService.updateDelflag(ids).get())
            map.put("msg", "删除成功");
        else
            map.put("msg", "数据操作异常");
        return map;
    }


}
